<template>
  <div class="login-container">
    <video class="video" muted src="../../assets/video/sky.mp4" loop="loop" autoplay></video>

    <!-- 常规登入 -->
    <el-form :model="loginForm" status-icon :rules="rules" ref="loginForm" label-width="100px" class="demo-loginForm">
      <h1 class="title" v-text="title"></h1>

      <!-- 一开始是二维码角标,点击之后变成电脑角标,再次点击又切换 -->
      <svg @click="(isErweiLogin = !isErweiLogin), (isSmsLogin = false)" :class="['jiaobiao', 'icon']"
        aria-hidden="true">
              <use :xlink:href="jiaobiao"></use>
          </svg>


      <!-- 账号密码登入 -->
      <div class="common-login" v-if="!isErweiLogin && !isSmsLogin">
        <el-form-item label="用户名" prop="username" class="first">
          <el-input type="test" v-model="loginForm.username" autocomplete="on"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input type="password" v-model="loginForm.password" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="验证码" prop="captcha">
          <el-input maxlength="5" v-model="loginForm.captcha" class="captcha" ref="captcha"
            @keydown.native.enter="submitForm('loginForm')"></el-input>
          <span class="captcha-svg" v-loading="loading">
            <i @click="updateCaptcha" v-html="captchaSvg"></i>
          </span>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm('loginForm')">提交</el-button>
        </el-form-item>
        <!-- 手机登入图标按钮 -->
        <el-form-item>
          <div class="sms">
            <svg class="icon phone" aria-hidden="true">
              <use xlink:href="#icon-iphone"></use>
            </svg>
            <a href="javascript:;" @click="isSmsLogin = true" style="color: #fff; font-size: 16px">切换短信登入</a>
          </div>
        </el-form-item>
        <!-- <el-form-item>
              <el-button type="primary" @click="submitForm('loginForm')">登入</el-button>
          </el-form-item> -->
      </div>

      <!-- 二维码登入 -->
      <div class="erwei" v-else-if="isErweiLogin && !isSmsLogin">
        <div class="img" v-loading="qrloading">
          <img :src="imgBase64Url" width="200px">
          <i class="mask" :style="qrStyle" v-show="showQrMask" @click="getQrcode"></i>
        </div>
        <p>
          <svg aria-hidden="true" class="icon-wx">
            <use xlink:href="#icon-weixin"></use>
          </svg>
          <b v-text="qrTip"></b>
        </p>
      </div>

      <!-- 短信验证码登入 -->
      <div class="smsContainer" v-else>
        <el-form-item label="手机号">
          <el-input maxlength="11" v-model="phoneNumber" class="captcha phone"></el-input>
          <span @click="sendSmsCode" v-text="smsRetryMsg"
            style="color: #888; line-height: 45px; text-decoration: underline">
          </span>
        </el-form-item>
        <el-form-item label="验证码">
          <el-input v-model="smsCode"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="smsSubmit">提交</el-button>
        </el-form-item>
      </div>
    </el-form>
  </div>
</template>
<script>
//引入api中的方法
import * as api from "@/api/users";
//引入二维码成功和失效的图片
import scancodeSuccessPic from "../../assets/img/scancode.png"
import invalidPic from "../../assets/img/invalidQr.png"
//引入socket.io
import socketIo from "socket.io-client"
//引入生成二维码的插件qrcode
import qr, { toDataURL } from "qrcode"
//映射vuex
import { mapMutations } from "vuex"


//校验验证码
var validateCaptcha = (rule, value, callback) => {
  if (!value) {
    callback("发送验证码")
  } else {
    callback()
  }
};
//用户名的校验函数
var validateUsername = (rule, value, callback) => {
  //console.log(value);
  let pattarn = /^[a-zA-Z0-9_-]{2,16}$/;
  if (pattarn.test(value)) {
    callback()    //回调函数不传参就是通过
  } else {
    callback("4-16位（字母，数字，下划线）")
  }
};
//密码校验函数
var validatePassword = (rule, value, callback) => {
  if (value === '') {
    callback(new Error('请输入密码'));
  } else {
    callback()
  }
};
export default {
  data() {
    return {
      loginForm: {
        //登入输入框的数据
        username: '',
        password: '',
        captcha: '',
      },
      captchaSvg: "",      //验证码svg
      codeLoading: false,    //验证码加载动画
      loading: true,     //加载动画布尔值
      isErweiLogin: false,    //是否是二维码登录
      title: "千峰管理系统",
      isSmsLogin: false,    //是否手机验证码登录
      imgBase64Url: "",      //二维码base64的图片地址
      isScanCodeSuccess: false, //是否扫码成功
      showQrMask: false,     //是否显示二维码遮罩
      qrloading: true,     //加载二维码的动画
      qrTip: "请使用手机微信扫码登入", //切换到二维码登入时的提示文字
      smsRetryMsg: "点击发送验证码", //xx秒之后重新发送提示
      smsDisabled: false,    //控制是否能够再次发送
      phoneNumber: "",    //手机号
      smsCode: "",
      smsDisabled: false,
      qrStyle: {
        backgroundImage: `url(${invalidPic})`
      },


      rules: {
        username: [
          { validator: validateUsername, trigger: 'blur' }
        ],
        password: [
          { validator: validatePassword, trigger: 'blur' }
        ],
        captcha: [
          { validator: validateCaptcha, trigger: 'blur' }
        ]
      }
    };
  },
  //计算属性
  computed: {
    jiaobiao() {
      return this.isErweiLogin ? '#icon-diannaojiaobiao' : '#icon-erweimajiaobiao'
    }
  },
  created() {
    //调用获取验证码的方法
    this.updateCaptcha()
  },
  methods: {
    //映射vuex
    ...mapMutations(["SET_USERINFO"]),
    //常规登录
    async submitForm(formName) {
      //登入逻辑
      //1.先要进行本地的表单校验
      //2.表单校验通过之后 通过v-model获取输入的username password
      //3.校验验证码
      //4.校验通过之后 发起请求 请求登入接口 传入用户名和密码
      //5.跳转到主页,显示主页
      //fromName是表单的ref名字
      //console.log(this.$refs);
      this.$refs[formName].validate((valid) => {
        //console.log(valid);    //登入成功就是true，没登上就是false
        if (valid) {
          //打开加载动画
          const loading = this.$loading({
            lock: true,
            text: '正在登录',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)'
          });

          //本地表单验证通过
          //alert('submit!');
          let { username, password, captcha } = this.loginForm

          //校验验证码
          api.verifyCaptcha(captcha).then(async res => {
            //console.log(res);
            let { state, msg } = res.data
            if (state) {
              //验证码正确
              let loginRes = await api.login(username, password)
              //console.log(loginRes);
              let { state: loginState, msg, token, userInfo } = loginRes.data;
              if (loginState) {
                //登录成功了
                //关闭加载动画
                loading.close();
                //将token存到localStorage
                localStorage.setItem("myx-token", token)
                //调用vuex的方法设置用户信息
                this.SET_USERINFO(userInfo)
                //要跳转页面
                this.$router.push("/")
                //提示登录成功
                this.$message({
                  message: msg,
                  type: "success",
                  duration: 1000    //提示收起来的时间
                })
              } else {
                //登录失败，关闭loading动画
                loading.close();
              }
            } else {
              //验证码校验失败
              loading.close();
              //刷新验证码
              this.updateCaptcha()
              this.captcha = ""
            }
          })
        } else {
          //表单验证不通过
          //console.log('error submit!!');
          return false;
        }
      });
    },
    //短信登录
    async smsSubmit() {
      let smsLoginRes = await api.smsLogin(this.smsCode)
      console.log(smsLoginRes);
      //判断登录状态，如果登录成功，将数据存储到本地
      let {
        userInfo,
        state,
        permission: { buttons },
        token,
      } = smsLoginRes.data;
      if (state) {
        //localStorage.setItem("myx-userInfo", JSON.stringify(userInfo));
        localStorage.setItem("myx-permissionBtn", JSON.stringify(buttons));
        localStorage.setItem("myx-token", token);
        //调用vuex的方法设置用户信息
        this.SET_USERINFO(userInfo)
        //跳转到欢迎页
        this.$router.push("/");
      }
      //打开加载动画

      //按钮权限
    },
    //扫码登录
    async getQrcode(sid) {
      //将文字提示变更
      this.qrTip = "请使用手机微信扫码登入"
      //先清掉上一次二维码
      this.imgBase64Url = ""
      //先关掉遮罩
      this.showQrMask = false
      //打开加载动画
      this.qrloading = true
      //封装一个获取二维码地址的方法
      sid = localStorage.getItem("myx-sid") ?? sid  //如果有的话，就输出本地存储的sid，没有的话，就输出传过来的sid
      console.log(sid);
      //关掉qrcode的遮罩
      //让遮罩的样式初始化
      //从本地取出sid
      //调用接口获取二维码url
      let qrResult = await api.getQrcode(sid)
      //console.log(qrResult);
      //解构qrcodeurl 和 后端的状态
      let { scanCodeUrl, state: getQrState } = qrResult.data
      //console.log(scanCodeUrl);
      //判断状态
      if (getQrState) {
        //如果请求成功，使用qrcode插件，将上面那个变成二维码
        qr.toDataURL(scanCodeUrl, (err, imgBase64Url) => {
          if (err) {   //出错的情况
            this.$messageBox.error(err)
            return
          }
          //console.log(imgBase64Url);
          this.imgBase64Url = imgBase64Url
          //设置成功，就可以关掉二维码动画了
          this.qrloading = false
        })
      }
    },
    updateCaptcha() {
      //封装一个方法，专门用于获取验证码
      //打开加载动画
      this.loading = true
      api.getCaptcha().then(res => {
        //console.log(res);    //得到验证码的数据
        let img = res.data.img; //解构验证码
        this.captchaSvg = img
        //关闭加载动画
        this.loading = false
      })
    },
    async sendSmsCode() {
      //封装短信登入的相关方法
      console.log(this.phoneNumber);
      //判断一下是否可以发送短信，通过smsDisabled来控制
      if (this.smsDisabled) {
        this.$message.error("1分钟内只能发送一次")
        return   //后面的逻辑不执行
      }
      //获取手机号，传递给后台，调用发送短信的接口
      let smsResult = await api.getSmsCode(this.phoneNumber)
      //先解构内容
      let { state } = smsResult.data
      if (state) {
        //锁住smsDisabled，不能再次发送了
        this.smsDisabled = true
        //提示用户短信发送成功
        this.$message.success("短信发送成功")
        //短信进入倒计时
        this.smsSecond = 60
        this.smsInterval = setInterval(() => {
          this.smsSecond--
          if (this.smsSecond === 0) {
            clearInterval(this.smsInterval)
            //提示文字复用
            this.smsRetryMsg = "点击发送验证码";
            //解锁smsDisabled，可以继续发送短信了
            this.smsDisabled = false
            return
          }
          this.smsRetryMsg = `${this.smsSecond}秒后重新发送`
        }, 1000)
      }

      console.log(smsResult);
    }
  },
  watch: {
    //监听切换短信登入逻辑
    isSmsLogin(val) {
      //不是短信登入的时候,清掉定时器
      if (!val) {
        if (this.smsInterval) {
          clearInterval(this.smsInterval);
        }
        //将短信登入的文字提示复原
        this.smsRetryMsg = "点击发送验证码";
      }
    },
    //监听切换二维码登入的字段
    isErweiLogin(isErwei) {
      if (isErwei) {
        //切换成了二维码登入
        //打开二维码加载动画
        this.qrLoading = true;
        //需要把遮罩关掉
        this.showQrMask = false;
        //建立socket 连接
        //https协议,要使用wss协议
        let io = socketIo("wss://chst.vip");
        //扫码成功
        io.on("scancodeSuccess", async (data) => {
          //显示二维码的遮罩 并且将背景图片换成扫码成功的背景图片
          this.showQrMask = true;
          this.qrStyle.backgroundImage = `url(${scancodeSuccessPic})`;
          // console.log(data);
          //先解构内容
          let { state: scanCodeState, wechatCode } = data;
          if (scanCodeState) {
            //扫码成功了
            let scanCodeRes = await api.wechatLogin(wechatCode);
            // console.log(scanCodeRes);
            //解构内容
            let {
              state,
              userInfo,
              permission: { buttons },
              token,
            } = scanCodeRes.data;
            //把token userInfo permission存本地
            if (state) {
              localStorage.setItem("myx-userInfo", JSON.stringify(userInfo));
              localStorage.setItem(
                "myx-permissionBtn",
                JSON.stringify(buttons)
              );
              localStorage.setItem("myx-token", token);
              //调用vuex的方法,设置用户信息
              this.SET_USERINFO(userInfo);
              //跳转到欢迎页
              this.$router.push("/");
              //调用vuex的方法设置用户信息
              this.SET_USERINFO(userInfo)
              //关闭二维码遮罩
              this.showQrMask = false;
            }
          }
        });
        //二维码失效
        io.on("invalidCode", (data) => {
          // console.log(data);
          let { state } = data;
          if (!state) {
            this.showQrMask = true;
            //将提示文字变更
            this.qrTip = "二维码失效,请点击重新获取二维码";
          }
        });
        //连接成功
        io.on("connectSuccess", async (data) => {
          // console.log(data);
          //从data中解构sid
          let { sid } = data;
          //把唯一标识存到本地
          localStorage.setItem("myx-sid", sid);
          //调用获取二维码的方法
          this.getQrcode(sid);
        });
      }
    },
  },
}
</script>
<style scoped lang="less">
//样式设置不上的情况,解决方案
//1.检查类名是否正确
//2.检查权重是否正确
//3.检查是否需要穿透
.icon-wx {
  width: 25px !important;
  height: 25px !important;
  vertical-align: -7px;
  margin-right: 3px;
}

.login-container {
  text-align: center;
  color: #fff;

  .common-login {
    padding-right: 50px;
  }

  //二维码样式
  .erwei .img {
    display: inline-block;
    position: relative;
    width: 200px;
    height: 200px;

    img {
      position: absolute;
      left: 0;
    }

    .mask {
      width: 100%;
      height: 100%;
      opacity: 0.8;
      background-color: #fff;
      position: absolute;
      left: 0;
      // background-image: url("../../assets/img/scancode.png");
      background-size: 50%;
      background-repeat: no-repeat;
      background-position: center;
      cursor: pointer;
    }
  }

  .jiaobiao {
    font-size: 60px;
    color: #fff;
    position: absolute;
    right: -1px;
    top: -1px;
    cursor: pointer;
    opacity: 0.7;
  }

  .video {
    position: fixed;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
  }

  .bg2 {
    background-image: url("../../assets/img/bg2.png");
    background-repeat: no-repeat;
    position: fixed;
    width: 20%;
    height: 40%;
    background-size: 100% 100%;
    left: 20%;
    top: 40%;
    opacity: 0.5;
  }

  .el-form {
    position: fixed;
    right: 10%;
    top: 25%;
    border-radius: 5px;
    width: 400px;
    background-color: rgba(0, 0, 0, 0.3);
    padding: 100px 0 50px 0;

    /deep/ .el-input__inner {
      width: 250px;
    }

    /deep/ .el-button--primary {
      background: linear-gradient(90deg, #1596fb, #002dff);
      width: 250px;
    }

    /deep/ .el-form-item__label {
      color: #fff;
    }

    .title {
      margin: 0 0 60px 0;
      text-align: center;
      color: #fff;
    }

    /deep/ .captcha {
      width: 100px;
      vertical-align: top;

      .el-input__inner {
        width: 100%;
        height: 45px;
        border-radius: 5px 0 0 5px;
        border: 0;
        font-size: 18px;
      }
    }

    svg path {
      stroke: red;
    }

    .captcha-svg {
      background: #fff;
      display: inline-block;
      height: 45px;
      width: 150px;
      text-align: center;
      cursor: pointer;
      border: 0;
      border-radius: 0px 5px 5px 0;
    }

    .el-form-item__content {
      margin-left: 30px !important;
      width: 250px !important;
    }
  }
}

.sms {
  margin-left: -15px !important;
  width: 250px !important;
}

.smsContainer {
  padding-right: 20px !important;
  width: 89%;

  /deep/ .el-form-item__label {
    // margin-left: 80px !important
    padding: 0 !important;
    padding-right: 10px !important;
  }

  /deep/ .phone {
    width: 140px !important;
  }

  /deep/ .captcha-svg {
    width: 115px !important;
  }

  /deep/ .el-form-item__content {
    margin: 0;
  }
}

// .smsContainer{
// 	width:300px;
// }
</style>